
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>

using namespace std::chrono_literals;

namespace {

std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;

void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cout << "Waiting... \n";
    cv.wait(lk, []{return i == 1;});
    std::cout << "...finished waiting; i == " << i << '\n';
    done = true;
}

void signals()
{
    std::this_thread::sleep_for(200ms);
    std::cout << "Notifying falsely...\n";
    // 等待线程被唤醒时Predicate判断不通过，继续等待唤醒
    cv.notify_one(); // waiting thread is notified with i == 0.
                     // cv.wait wakes up, checks i, and goes back to waiting

    std::unique_lock<std::mutex> lk(cv_m);
    i = 1;
    while (!done)
    {
        std::cout << "Notifying true change...\n";
        lk.unlock();
        // 变量已被设置，等待线程可继续进行
        cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns
        // sleep后再加锁，防止被唤醒线程获取不到锁
        std::this_thread::sleep_for(300ms);
        lk.lock();
    }
}

void Handle() {

    std::thread t1(waits), t2(signals);
    t1.join();
    t2.join();
}

}

void HandleMutex() {
    Handle();
}
